package com.wyz.socket.core.impl;

import com.wyz.socket.core.base.Context;
import com.wyz.socket.core.impl.chain.AbstractCloseChain;
import com.wyz.socket.core.impl.chain.AbstractStringPacketChain;
import com.wyz.socket.core.base.packet.AbstractReceivePacket;
import com.wyz.socket.core.base.packet.Packet;
import com.wyz.socket.core.base.packet.string.StringReceivePacket;
import com.wyz.socket.core.utils.FileUtils;
import com.wyz.socket.core.utils.Log;

import java.io.*;
import java.nio.channels.SocketChannel;

/**
 * socket channel 包装类
 */
public class ConnectorHandler extends Connector {

    private final File cacheFile;

    public ConnectorHandler(SocketChannel socketChannel, File cacheFile) throws IOException {
        super(socketChannel.getRemoteAddress().toString());
        this.cacheFile = cacheFile;
        this.onStart(socketChannel);
        Log.printlnInfo("ConnectorHandler", "新客户端连接完成 : " + getClientInfo() + ":" + socketChannel.socket().getPort());
    }

    @Override
    protected File createFile(int length, byte[] headerInfo) {
        return FileUtils.createRandomFile(cacheFile);
    }

    @Override
    protected OutputStream createOutputStream(int length, byte[] headerInfo) {
        return new ByteArrayOutputStream(length);
    }

    public String getClientInfo() {
        return clientInfo;
    }

    @Override
    protected void onReceivedPacket(AbstractReceivePacket<?, ?> packet) {
        switch (packet.type()) {
            case Packet.TYPE_MEMORY_STRING: {
                Context.get().getScheduler().execute(() -> printChain.handle(this, (StringReceivePacket) packet));
                break;
            }
            default:
                Log.printlnInfo("ConnectorHandler", "类型未知: type = " + packet.type() + "  length = " + packet.length());
        }
    }

    public AbstractStringPacketChain getPrintChain() {
        return printChain;
    }

    public AbstractCloseChain getCloseChain() {
        return closeChain;
    }

    @Override
    public <T> void onClose(T t) {
        if (t instanceof SocketChannel) {
            closeChain.handle(this, this);
        }
    }
}
